In [1]:
import ff
I used 3 as the generator for this field. For a field defined with the polynomial x^8 + x^4 + x^3 + x + 1, there may be other generators (I can't remember)
In [2]:
generator = ff.GF256int(3)
generator
Out[2]:
Multiplying the generator by itself is the same as raising it to a power. I show up to the 3rd power here
In [3]:
generator*generator
Out[3]:
In [4]:
generator*generator*generator
Out[4]:
In [5]:
generator**1
Out[5]:
In [6]:
generator**2
Out[6]:
In [7]:
generator**3
Out[7]:
The slow multiply method implemented without the lookup table has the same results
In [8]:
generator.multiply(generator)
Out[8]:
In [9]:
generator.multiply(generator.multiply(generator))
Out[9]:
We can enumerate the entire field by repeatedly multiplying by the generator. (The first element is 1 because generator^0 is 1). This becomes our exponent table.
In [10]:
exptable = [ff.GF256int(1), generator]
for _ in range(254): # minus 2 because the first 2 elements are hardcoded
exptable.append(exptable[-1].multiply(generator))
# Turn back to ints for a more compact print representation
print([int(x) for x in exptable])
That's now our exponent table. We can look up the nth element in this list to get generator^n
In [11]:
exptable[5] == generator**5
Out[11]:
In [12]:
all(exptable[n] == generator**n for n in range(256))
Out[12]:
In [13]:
tuple(int(x) for x in exptable) == ff.GF256int.exptable
Out[13]:
The log table is the inverse function of the exponent table
In [14]:
logtable = [None for _ in range(256)]
# Ignore the last element of the field because fields wrap back around.
# The log of 1 could be 0 (g^0=1) or it could be 255 (g^255=1)
for i, x in enumerate(exptable[:-1]):
logtable[x] = i
print([int(x) if x is not None else None for x in logtable])
In [15]:
tuple(int(x) if x is not None else None for x in logtable) == ff.GF256int.logtable
Out[15]:
In [ ]: